package com.hb.webapp.controller;

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.hb.Constants;
import com.hb.model.Role;
import com.hb.model.User;
import com.hb.service.RoleManager;
import com.hb.service.UserExistsException;
import com.hb.service.UserManager;
import com.hb.webapp.util.RequestUtil;

/**
 * Implementation of <strong>SimpleFormController</strong> that interacts with
 * the {@link UserManager} to retrieve/persist values to the database.
 *
 * <p><a href="UserFormController.java.html"><i>View Source</i></a>
 *
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 */
@Controller
public class UserFormController extends BaseFormController {
    private RoleManager roleManager;

    @Autowired
    public void setRoleManager(RoleManager roleManager) {
        this.roleManager = roleManager;
    }

    public UserFormController() {
        setCancelView("redirect:/mainMenu");
        setSuccessView("redirect:/admin/users");
    }

    @RequestMapping(method = RequestMethod.POST, value="/editfn")
    public ModelMap editFullName(User user, BindingResult errors, HttpServletRequest request, HttpServletResponse response) throws Exception{
    	User cleanUser = getUserManager().getUserByUsername(request.getRemoteUser());
    	log.debug("entering 'editFullName' method...");
    	cleanUser.setFirstName(user.getFirstName());
    	log.debug("set firstname: " + user.getFirstName());
    	cleanUser.setLastName(user.getLastName());
    	log.debug("set lastname: " + user.getLastName());
    	
        try {
            getUserManager().saveUser(user);
        } catch (AccessDeniedException ade) {
            // thrown by UserSecurityAdvice configured in aop:advisor userManagerSecurity
            log.warn(ade.getMessage());
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return null;
        }
        
        ModelMap map = new ModelMap();
        map.put("status", true);
        map.put("message", "");
        return map;
    }
    
//    @RequestMapping(method = RequestMethod.POST, value="/userform*")
//    public String onSubmit(User user, BindingResult errors, HttpServletRequest request,
//                           HttpServletResponse response)
//            throws Exception {
//        if (request.getParameter("cancel") != null) {
//            if (!StringUtils.equals(request.getParameter("from"), "list")) {
//                return getCancelView();
//            } else {
//                return getSuccessView();
//            }
//        }
//
//        if (validator != null) { // validator is null during testing
//            validator.validate(user, errors);
//
//            if (errors.hasErrors() && request.getParameter("delete") == null) { // don't validate when deleting
//                return "userform";
//            }
//        }
//
//        log.debug("entering 'onSubmit' method...");
//
//        Locale locale = request.getLocale();
//
//        if (request.getParameter("delete") != null) {
//            getUserManager().removeUser(user.getId().toString());
//            saveMessage(request, getText("user.deleted", user.getFullName(), locale));
//
//            return getSuccessView();
//        } else {
//
//            // only attempt to change roles if user is admin for other users,
//            // showForm() method will handle populating
//            if (request.isUserInRole(Constants.ADMIN_ROLE)) {
//                String[] userRoles = request.getParameterValues("userRoles");
//
//                if (userRoles != null) {
//                    user.getRoles().clear();
//                    for (String roleName : userRoles) {
//                        user.addRole(roleManager.getRole(roleName));
//                    }
//                }
//            } else {
//                // if user is not an admin then load roles from the database
//                // (or any other user properties that should not be editable 
//                // by users without admin role) 
//                User cleanUser = getUserManager().getUserByUsername(
//                        request.getRemoteUser());
//                user.setRoles(cleanUser.getRoles());
//            }
//
//            Integer originalVersion = user.getVersion();
//
//            try {
//                getUserManager().saveUser(user);
//            } catch (AccessDeniedException ade) {
//                // thrown by UserSecurityAdvice configured in aop:advisor userManagerSecurity
//                log.warn(ade.getMessage());
//                response.sendError(HttpServletResponse.SC_FORBIDDEN);
//                return null;
//            } catch (UserExistsException e) {
//                errors.rejectValue("username", "errors.existing.user",
//                        new Object[]{user.getUsername(), user.getEmail()}, "duplicate user");
//
//                // redisplay the unencrypted passwords
//                user.setPassword(user.getConfirmPassword());
//                // reset the version # to what was passed in
//                user.setVersion(originalVersion);
//
//                return "userform";
//            }
//
//            if (!StringUtils.equals(request.getParameter("from"), "list")) {
//                saveMessage(request, getText("user.saved", user.getFullName(), locale));
//
//                // return to main Menu
//                return getCancelView();
//            } else {
//                if (StringUtils.isBlank(request.getParameter("version"))) {
//                    saveMessage(request, getText("user.added", user.getFullName(), locale));
//
//                    // Send an account information e-mail
//                    message.setSubject(getText("signup.email.subject", locale));
//
//                    try {
//                        sendUserMessage(user, getText("newuser.email.message", user.getFullName(), locale),
//                                RequestUtil.getAppURL(request));
//                    } catch (MailException me) {
//                        saveError(request, me.getCause().getLocalizedMessage());
//                    }
//
//                    return getSuccessView();
//                } else {
//                    saveMessage(request, getText("user.updated.byAdmin", user.getFullName(), locale));
//                }
//            }
//        }
//
//        return "userform";
//    }

    @ModelAttribute
    @RequestMapping(method = RequestMethod.GET, value="/userform*")
    protected User showForm(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // If not an administrator, make sure user is not trying to add or edit another user
        if (!request.isUserInRole(Constants.ADMIN_ROLE) && !isFormSubmission(request)) {
            if (isAdd(request) || request.getParameter("id") != null) {
                response.sendError(HttpServletResponse.SC_FORBIDDEN);
                log.warn("User '" + request.getRemoteUser() + "' is trying to edit user with id '" +
                        request.getParameter("id") + "'");

                throw new AccessDeniedException("You do not have permission to modify other users.");
            }
        }

        if (!isFormSubmission(request)) {
            String userId = request.getParameter("id");

            // if user logged in with remember me, display a warning that they can't change passwords
            log.debug("checking for remember me login...");

            AuthenticationTrustResolver resolver = new AuthenticationTrustResolverImpl();
            SecurityContext ctx = SecurityContextHolder.getContext();

            if (ctx.getAuthentication() != null) {
                Authentication auth = ctx.getAuthentication();

                if (resolver.isRememberMe(auth)) {
                    request.getSession().setAttribute("cookieLogin", "true");

                    // add warning message
                    saveMessage(request, getText("userProfile.cookieLogin", request.getLocale()));
                }
            }

            User user;
            if (userId == null && !isAdd(request)) {
                user = getUserManager().getUserByUsername(request.getRemoteUser());
            } else if (!StringUtils.isBlank(userId) && !"".equals(request.getParameter("version"))) {
                user = getUserManager().getUser(userId);
            } else {
                user = new User();
                user.addRole(new Role(Constants.USER_ROLE));
            }

            user.setConfirmPassword(user.getPassword());

            return user;
        } else {
            // populate user object from database, so all fields don't need to be hidden fields in form
            return getUserManager().getUser(request.getParameter("id"));
        }
    }

    private boolean isFormSubmission(HttpServletRequest request) {
        return request.getMethod().equalsIgnoreCase("post");
    }

    protected boolean isAdd(HttpServletRequest request) {
        String method = request.getParameter("method");
        return (method != null && method.equalsIgnoreCase("add"));
    }
}
